﻿

﻿package Memoir 
{
	import Main.Memoir;
	import Main.Preloader;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.utils.Timer;
	
	import mx.core.SoundAsset;
	
	import org.flixel.*;
	
	/**
	 * Game state representing a location/level.
	 * 
	 */
	public class PlayState extends FlxState
	{
		[Embed(source = '../Assets/blankLayer.png')] private var NoClick:Class;
		[Embed(source = '../Assets/filmstrip.png')] private var FilmStripImg:Class;
		[Embed(source = '../Assets/notebooksmall.png')] private var NotesSmallImg:Class;
		[Embed(source = '../Assets/notebooklarge.png')] private var NotesLargeImg:Class;
		[Embed(source='../Assets/PenguinScratch.otf', fontFamily="peng",embedAsCFF="false")] private var PenguinScratch:String;
	
		private var noClickLayer:FlxSprite = new FlxSprite(0,0,NoClick);
		private var notesSprite:FlxSprite = new FlxSprite(0,0,NotesSmallImg);
		private var bigNotesSprite:FlxSprite = new FlxSprite(0,0,NotesLargeImg);
		private var filmStrip:FlxSprite; 		
		private var notesButton:FlxButton;
		private var bigNotesButton:FlxButton;
		
		
		private static var player:Player = new Player;
		private static var cursor:Cursor = new Cursor;
		
		private var notesOpen:Boolean = false;
		private var notesCloseClicked:Boolean = false;
		private var shutterTimer:int = 0;
		private var lvlTxtBox:FlxText = new FlxText(15,505,110,getLvlTxt());
		private var promptBox:FlxText = new FlxText(300,120,220,getPrompt());
		
		
		private var currLevel:int = 0;
		private var level:int=0;
		private var negScore:Number = 0;
		private var neuScore:Number = 0;
		private var posScore:Number = 0;
		private var numHotSpotsHit:int = 0;
		
		private var hotSpotArray:Array;
		
		private var maxPos:Number = 0;
		private var maxPosMem:String = "";
		private var maxNeg:Number = 0;
		private var maxNegMem:String = "";
		private var maxNeu:Number = 0;
		private var maxNeuMem:String = "";
		
		private const fsLeft:uint = 150; // where is the left edge of the film strip?
		private const fsBtw:uint = 30; // how many pixels between pictures?
		
		//rating stuff
		[Embed(source = '../Assets/ok_rating.png')] private var OkRating:Class;
		[Embed(source = '../Assets/nice_rating.png')] private var NiceRating:Class;
		[Embed(source = '../Assets/great_rating.png')] private var GreatRating:Class;	
		private var niceRating:FlxSprite;
		private var greatRating:FlxSprite;
		private var rating:FlxSprite;
		private var rateTimer:int;
		private var ratingAll:FlxGroup;
		
		//sound stuff
		[Embed(source = '../Assets/cameraClick.mp3')] 
		public static var clickSFX:Class;
		[Embed(source = '../Assets/cameraRewind.mp3')] 
		public static var windSFX:Class;

		
		public function PlayState(lvl:int) 
		{			
			level = lvl;
			// set background color (gray)
			FlxState.bgColor = 0xFFdddddd;
			
			// add the level background image
			addBackground();
			
			// add the empty filmstrip
			filmStrip = new FlxSprite(fsLeft,500,FilmStripImg);
			this.add(filmStrip);
			
			// add the notebook button
			notesButton = new FlxButton(695,504,openNotes);
			notesButton.loadGraphic(notesSprite);
			this.add(notesButton);
			
			// create the larger notebook button
			// don't add it yet; it only pops up when you click the little button
			bigNotesButton = new FlxButton(250,50,closeNotes);
			bigNotesButton.loadGraphic(bigNotesSprite);			
			
			// add the player
			FlxG.mouse.hide();
			this.add(player);
		

			
			//set the hotspot array
			hotSpotArray = getHotSpots();	
			
			promptBox.setFormat("peng",28,0x000000);		

			lvlTxtBox.setFormat("peng",20,0x000000);
			this.add(lvlTxtBox);
		}
		
		// override me
		public function addBackground():void {
			return;
		}
		
		// override me
		public function getBackground():Object {
			return null;
		}
		
		public function getHotSpots():Array {
			return null;
		}
		
		// override me
		public function getLvlTxt():String {
			return "not a level text";
		}
		
		public function getPrompt():String {
			return "not a level prompt";
		}
		
		private function openNotes():void{
			if (notesOpen){return;}
			defaultGroup.remove(player);
			defaultGroup.add(noClickLayer);	
			this.add(bigNotesButton);
			defaultGroup.add(promptBox);
			defaultGroup.add(cursor);
			notesOpen = true;
		}
		
		private function closeNotes():void{		
			defaultGroup.remove(cursor);
			defaultGroup.remove(noClickLayer);
			defaultGroup.remove(bigNotesButton);
			defaultGroup.remove(promptBox);		
			notesCloseClicked = true;
		}	
		
		override public function update():void 
		{	
			///*  uncomment these lines to disable GodState
			if (FlxG.keys.justReleased("G")){
				FlxG.state = new GodState();
			}
			//*/
			super.update();
			shutterTimer -= FlxG.elapsed;
			rateTimer-=FlxG.elapsed;
			
			
			
			if ((FlxG.mouse.justReleased() || FlxG.keys.justPressed("SPACE"))
				&& FlxG.mouse.y < 499
				&& shutterTimer<=0)
			{
				if (notesOpen){
					if(notesCloseClicked){
						notesOpen = false;
						notesCloseClicked = false;
						defaultGroup.add(player);	
					}
					return;
				}
				shutterTimer = 50;
				FlxG.play(clickSFX,1,false);
				player.play("snap");
				//trace("Click!");
				defaultGroup.remove(rating);
				hotSpotScanner(FlxG.mouse.x,FlxG.mouse.y);
				//				var picScore:Number = 
				//				if (!isNaN(picScore)) {
				//					levelScore += picScore;
				//				}
				takePicture(Math.min(FlxG.mouse.x,709),Math.min(FlxG.mouse.y,409));				
			}
			else if(shutterTimer<=0 && FlxG.mouse.y <500)
			{
				player.play("normal");
			}
			else if (FlxG.mouse.y > 499){
				player.play("standin");
			}
			
			if(rateTimer<=0)
			{
				
				defaultGroup.remove(rating);
				rateTimer=0;
				
			}
		}
		
		/** This function takes pictures! */
		private var picNum:uint = 0;  // next spot to be filled on film strip
		private var film:Bitmap = new FilmStripImg();
		private var background:Bitmap = getBackground() as Bitmap;
		public function takePicture(topleft_x:uint, topleft_y:uint):void 
		{
			if (topleft_x > 709 || topleft_y > 409 ) 
			{
				return;  // don't take a picture
			}	
			if (picNum < 4) 
			{
				var sourceRect:Rectangle = new Rectangle(topleft_x,topleft_y,90,90);
				//var destX:uint = 8+picNum*98;
				var destX:uint = fsBtw+picNum*(fsBtw+90);
				var destPoint:Point = new Point(destX,5);
				film.bitmapData.copyPixels(background.bitmapData, sourceRect, destPoint);
				
				var newFilmStrip:FlxSprite = new FlxSprite(fsLeft,500);
				newFilmStrip.pixels = film.bitmapData;
				this.defaultGroup.replace(filmStrip,newFilmStrip);
				filmStrip = newFilmStrip;
				picNum = picNum+1;
			}
			if (picNum==4){ 
				defaultGroup.remove(player);
				defaultGroup.remove(cursor);
				//var endtxt:FlxText = new FlxText(100,100,650,"out of film!");
				//endtxt.setFormat("peng",72,0x000000,"center");
				//var endsprite:FlxSprite = new FlxSprite(80,80);
				//endsprite.createGraphic(FlxG.width-160,200,0xdddddddd);
				//defaultGroup.add(endsprite);
				//defaultGroup.add(endtxt);
				
				advance();	
			}
		}

		
		private function advance():void{
			FlxG.play(windSFX,1,false);
			shutterTimer = 2700;	// disable clicking for the rest of the level's time
			var timer:Timer = new Timer(2500,1);	// when started, waits 2.5 seconds 
			timer.addEventListener(TimerEvent.TIMER_COMPLETE,onTimerComplete); //trigger the 1sec fade out
			
			timer.start();
		}
		
		private function onTimerComplete(event:TimerEvent):void{			
			FlxG.fade.start(0xff000000, 1, onFade);		
		}
		private function onFade():void  
		{
			var alignment:int;
			trace("total scores: "+posScore + " "+neuScore+" "+negScore);
			if (numHotSpotsHit == 0) {
				FlxG.state = new Memoir.OldLadyState(10,10,"",this.filmStrip); //level and alignemnt = 10 means you're fired! 
			} else {
				if (posScore >= neuScore && posScore >= negScore) {
					alignment = 1;
					Main.Memoir.alignments.push(Main.Memoir.POSITIVE);
					trace("postive added");
					FlxG.state = new Memoir.OldLadyState(level+1, alignment, maxPosMem,this.filmStrip); 
				} else if (negScore >= neuScore && negScore >= neuScore) {
					alignment = -1;
					Main.Memoir.alignments.push(Main.Memoir.NEGATIVE);
					trace("negative added");
					FlxG.state = new Memoir.OldLadyState(level+1,alignment, maxNegMem,this.filmStrip); 
				} else {
					alignment = 0;
					Main.Memoir.alignments.push(Main.Memoir.NEUTRAL);
					trace("neutral added");
					FlxG.state = new Memoir.OldLadyState(level+1,alignment, maxNeuMem,this.filmStrip); 
				}
				
			}
		}
		
		
		public function hotSpotScanner(X:Number,Y:Number):void
		{
			//trace("Scanning");
			var centerX:int=X+50;
			var centerY:int=Y+50;
			var counter:int;
			/*
			scanning just the center point of camera. 
			If it doesn't overlap with the hotspot at all, 
			I figure it's a crappy picture. We may want to 
			adjust/expand this so that there's a bit more "hinting"
			*/
			var score:Number;
			
			for(counter=0; counter<hotSpotArray.length; counter++)
			{
				//trace("Center: "+centerX+" hotspot x: "+ hotSpotArray[counter]._x +" hotspot x far: "+(hotSpotArray[counter]._x+hotSpotArray[counter]._width));
				//trace(hotSpotArray[counter]._alignment);
				//trace(centerX+" "+centerY);
				
				if(centerX>hotSpotArray[counter]._x && centerX<(hotSpotArray[counter]._x+hotSpotArray[counter]._width))
				{
					if(centerY>hotSpotArray[counter]._y && centerY<(hotSpotArray[counter]._y+hotSpotArray[counter]._height))
					{
						score = photoRater(hotSpotArray[counter], X, Y);
						if (hotSpotArray[counter]._alignment == Main.Memoir.NEGATIVE) {
							negScore += score;
							if (score > maxNeg) {
								maxNeg = score;
								maxNegMem = hotSpotArray[counter]._memory;
							}
						} else if (hotSpotArray[counter]._alignment == Main.Memoir.NEUTRAL) {
							neuScore += score
							if (score > maxNeu) {
								maxNeu = score;
								maxNeuMem = hotSpotArray[counter]._memory;
							}
						} else if (hotSpotArray[counter]._alignment == Main.Memoir.POSITIVE) {
							posScore += score
							if (score > maxPos) {
								maxPos = score;
								maxPosMem = hotSpotArray[counter]._memory;
							}
						}
						numHotSpotsHit ++;
					}
				}
			}
			//trace("score"+ score);
			//return score;
		}
		
		public function photoRater(hotSpot:Hotspot,X:Number,Y:Number):Number
		{
			var xOverlap:Number;
			var yOverlap:Number;
			var totalOverlap:Number;
			
			trace("Player X: "+X);
			trace("Player Y: "+Y);
			
			if(hotSpot._x>=player.x)
			{
				
				if(hotSpot._y <= player.y)
				{
					xOverlap=((X+player.width)-hotSpot._x)/(player.width);
					yOverlap=(player.y-(hotSpot._y+hotSpot._height))/(player.height);
				}
				else if(hotSpot._y>player.y)
				{
					xOverlap=((X+player.width)-hotSpot._x)/(player.width);
					yOverlap=((player.y+player.height)-(hotSpot._y))/(player.height);
					
				}
			}
			else if(hotSpot._x < player.x)
			{
				if(hotSpot._y <= player.y)
				{
					
					xOverlap=((X)-(hotSpot._x+hotSpot._width))/(player.width);
					yOverlap=(player.y-(hotSpot._y+hotSpot._height))/(player.height);
					
				}
					
				else if(hotSpot._y>player.y)
				{
					xOverlap=((X)-(hotSpot._x+hotSpot._width))/(player.width);
					yOverlap=((player.y+player.height)-(hotSpot._y))/(player.height);
					
				}
			}
			
			if(xOverlap>1||xOverlap<-1)
			{
				xOverlap=1;
			}
			if(yOverlap>1||yOverlap<-1)
			{
				yOverlap=1;
			}
			totalOverlap=xOverlap*yOverlap;
			totalOverlap=Math.abs(totalOverlap);
			trace("X Overlap: "+xOverlap+" Y Overlap: "+yOverlap);
			rateFeedback(totalOverlap);
			return totalOverlap;			
		}
		
		public function rateFeedback(score:Number):void{
			//add the rating buttons
			
			
			
	
			trace("Test:"+score+" "+player.x+" "+player.y);
			if(score<.6)
			{
				rating=new FlxSprite(player.x+90,player.y-20,OkRating);
				
				
			
			}
			else if(score<.9)
			{
				
				rating=new FlxSprite(player.x,player.y,NiceRating);
				
			}
			else
			{
				rating=new FlxSprite(player.x,player.y,GreatRating);
				
			}
			
			defaultGroup.add(rating);
			rateTimer=100;


		}
		
	}
}

